﻿using QuanLyGiaoVuService.CommandServices;
using QuanLyGiaoVuService.CommonServices;
using QuanLyGiaoVuService.ReportServices;
using QuanLyGiaoVuUI.Models.GiangVien;
using QuanLyGiaoVuUI.Models.LopMonHoc;
using QuanLyGiaoVuUI.Models.MonHoc;
using QuanLyGiaoVuUI.Models.Mappers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using QuanLyGiaoVuService.Domain;
using System.IO;
using QuanLyGiaoVuService.Utilities;
using QuanLyGiaoVuUI.Extensions.ExtendedAttributes;
using QuanLyGiaoVuUI.Models.GiangVienClient;
using QuanLyGiaoVuUI.Extensions.Utilities;
using QuanLyGiaoVuDAL.DTO;
using QuanLyGiaoVuUI.Models.XepLich;

namespace QuanLyGiaoVuUI.Controllers
{
    [GiangVienAuthorize]
    public class LopMonHocController : Controller
    {
        private ILopMonHocReportService _lopMonHocReportService;
        private ILopMonHocCommandService _lopMonHocCommandService;
        private IHocKyReportService _hocKyReportService;
        private ITietHocService _tietHocService;
        private IMonHocReportService _monHocReportService;
        private IGiangVienReportService _giangVienReportService;
        private ILichThiReportService _lichThiReportService;
        private ILichThiCommandService _lichThiCommandService;
        private IThamSoService _thamSoService;
        private IExcelService _excelService;
        private IDeTaiReportService _deTaiReportService;
        private IDeTaiCommandService _deTaiCommandService;
        private ITaiLieuReportService _taiLieuReportService;
        private IFileService _fileService;

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public LopMonHocController(ILopMonHocReportService lopMonHocReportService,
            ILopMonHocCommandService lopMonHocCommandService,
            IHocKyReportService hocKyReportService,
            ITietHocService tietHocService,
            IMonHocReportService monHocReportService,
            IGiangVienReportService giangVienReportService,
            ILichThiReportService lichThiReportService,
            IThamSoService thamSoService,
            IExcelService excelService,
            IDeTaiReportService deTaiReportService,
            IDeTaiCommandService deTaiCommandService,
            ITaiLieuReportService taiLieuReportService,
            IFileService fileService,
            ILichThiCommandService lichThiCommandService)
        {
            _lopMonHocReportService = lopMonHocReportService;
            _lopMonHocCommandService = lopMonHocCommandService;
            _hocKyReportService = hocKyReportService;
            _tietHocService = tietHocService;
            _monHocReportService = monHocReportService;
            _giangVienReportService = giangVienReportService;
            _lichThiReportService = lichThiReportService;
            _thamSoService = thamSoService;
            _excelService = excelService;
            _deTaiReportService = deTaiReportService;
            _deTaiCommandService = deTaiCommandService;
            _taiLieuReportService = taiLieuReportService;
            _fileService = fileService;
            _lichThiCommandService = lichThiCommandService;
        }

        public ActionResult Index()
        {
            ViewData["HocKyHienTai"] = (HocKyDTO)_hocKyReportService.GetHocKyById(_thamSoService.GetGuid(ThamSoConstantUtility.HOCKYHIENTAI));
            IEnumerable<LopMonHocViewModel> lopMonHocViewModel = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(new Guid(_thamSoService.GetThamSo(ThamSoConstantUtility.HOCKYHIENTAI)), null, null, true)).OrderBy(lop => lop.LopSinhVien.KhoaNam).OrderBy(lop => lop.MaMonHoc);
            return View(lopMonHocViewModel);
        }

        [HttpGet]
        public ActionResult DanhSachMoLopHocKySau()
        {
            ViewData["HocKyTiepTheo"] = (HocKyDTO)_hocKyReportService.GetHocKyById(_thamSoService.GetGuid(ThamSoConstantUtility.HOCKYTIEPTHEO));
            IEnumerable<LopMonHocViewModel> lopMonHocViewModel = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(new Guid(_thamSoService.GetThamSo(ThamSoConstantUtility.HOCKYTIEPTHEO)), null, null, true)).OrderBy(lop => lop.LopSinhVien.KhoaNam).OrderBy(lop => lop.MaMonHoc);
            return View(lopMonHocViewModel);
        }

        [HttpGet]
        public ActionResult CapNhat(Guid? id)
        {
            CapNhatLopMonHocViewModel viewModel = new CapNhatLopMonHocViewModel();
            var hocKyTiepTheo = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYTIEPTHEO);
            viewModel.MaHocKy = hocKyTiepTheo;
            if (id != null)
            {
                viewModel = viewModel.FromLopMonHocDTO(_lopMonHocReportService.GetLopMonHocById((Guid)id));
                viewModel.GiangVien1 = _giangVienReportService.GetGiangVienById(viewModel.MaGiangVien1);
                if (viewModel.MaGiangVien2 != null && !viewModel.MaGiangVien2.Equals(Guid.Empty))
                {
                    viewModel.GiangVien2 = _giangVienReportService.GetGiangVienById((Guid)viewModel.MaGiangVien2);
                }
                viewModel.DanhSachLopThucHanh = _lopMonHocReportService.GetAllLopMonHoc().Where(lop => lop.MaLopChinh == id.Value && lop.LoaiLop != 0);
                if (viewModel.Buoi1 != null)
                { 
                    viewModel.SC1 = viewModel.Buoi1.Value.Hour < 12 ? 0 : 1;
                }
                if (viewModel.Buoi2 != null)
                {
                    viewModel.SC2 = viewModel.Buoi2.Value.Hour < 12 ? 0 : 1;
                }
                if (viewModel.Buoi3 != null)
                {
                    viewModel.SC3 = viewModel.Buoi3.Value.Hour < 12 ? 0 : 1;
                }
            }
            viewModel.ChiLopThucHanh = false;
            viewModel.DanhSachHocKy = _hocKyReportService.GetAllHocKy().OrderBy(hk => hk.TenHocKy).OrderBy(hk => hk.NamHoc.Nam1);
            viewModel.DanhSachCa = _tietHocService.GetAllCa();
            viewModel.DanhSachLopSinhVien = _lopMonHocReportService.GetAllLopSinhVien().OrderBy(lop => lop.KhoaNam);
            viewModel.DanhSachTiet = _tietHocService.GetAllTietHoc(null, null, null);
            return View(viewModel);
        }

        [HttpGet]
        public ActionResult TaoLopThucHanh(Guid? maLopLyThuyet)
        {
            CapNhatLopMonHocViewModel viewModel = new CapNhatLopMonHocViewModel();
            if (maLopLyThuyet.HasValue)
            {
                var hocKyTiepTheo = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYTIEPTHEO);
                viewModel.MaHocKy = hocKyTiepTheo;
                var lopChinh = _lopMonHocReportService.GetLopMonHocById(maLopLyThuyet.Value);
                viewModel = viewModel.FromLopMonHocDTO(lopChinh);
                viewModel.MaLopChinh = lopChinh.LopMonHocId;
                viewModel.LopChinh = lopChinh;
                viewModel.LopMonHocId = Guid.Empty;
                viewModel.MaGiangVien1 = Guid.Empty;
                viewModel.GiangVien1 = null;
                viewModel.MaGiangVien2 = Guid.Empty;
                viewModel.GiangVien2 = null;
            }
            viewModel.DanhSachHocKy = _hocKyReportService.GetAllHocKy().OrderBy(hk => hk.TenHocKy).OrderBy(hk => hk.NamHoc.Nam1);
            viewModel.DanhSachCa = _tietHocService.GetAllCa();
            viewModel.DanhSachLopSinhVien = _lopMonHocReportService.GetAllLopSinhVien().OrderBy(lop => lop.KhoaNam);
            viewModel.DanhSachTiet = _tietHocService.GetAllTietHoc(null, null, null);
            viewModel.ChiLopThucHanh = true;
            viewModel.LoaiLop = ThamSoConstantUtility.LOAILOPTHUCHANH1;
            return View("CapNhat", viewModel);
        }

        [HttpPost]
        public ActionResult CapNhat(CapNhatLopMonHocViewModel viewModel)
        {
            viewModel.DongYMoLop = true;
            if (ModelState.IsValid)
            {
                var lopMonHocDTO = viewModel.ToLopMonHocDTO();
                if (lopMonHocDTO.LopMonHocId.Equals(Guid.Empty))
                    _lopMonHocCommandService.InsertLopMonHoc(lopMonHocDTO);
                else
                {
                    var oldLopMonHocDTO = _lopMonHocReportService.GetLopMonHocById(lopMonHocDTO.LopMonHocId);
                    lopMonHocDTO.GhiChu = oldLopMonHocDTO.GhiChu;
                    lopMonHocDTO.GiangVienXacNhan = oldLopMonHocDTO.GiangVienXacNhan;
                    lopMonHocDTO.DaXet = oldLopMonHocDTO.DaXet;
                    lopMonHocDTO.DaPhanHoi = oldLopMonHocDTO.DaPhanHoi;
                    if (!viewModel.CapNhatLichDay)
                    {
                        lopMonHocDTO.Thu = oldLopMonHocDTO.Thu;
                        lopMonHocDTO.TietDau = oldLopMonHocDTO.TietDau;
                        lopMonHocDTO.TietSau = oldLopMonHocDTO.TietSau;
                    }
                    else
                    {
                        if (lopMonHocDTO.MaTietDau > lopMonHocDTO.MaTietSau)
                        {
                            ModelState.AddModelError("MaTietDau", "Tiết đầu không được lớn hơn tiết sau");
                            viewModel.CapNhatLichDay = true;
                        }
                    }
                    if (viewModel.Buoi1 != null)
                    {
                        lopMonHocDTO.Buoi1 = new DateTime(lopMonHocDTO.Buoi1.Value.Year, lopMonHocDTO.Buoi1.Value.Month, lopMonHocDTO.Buoi1.Value.Day, viewModel.SC1 == 0 ? 8 : 13, 0, 0);
                    }
                    if (viewModel.Buoi2 != null)
                    {
                        lopMonHocDTO.Buoi2 = new DateTime(lopMonHocDTO.Buoi2.Value.Year, lopMonHocDTO.Buoi2.Value.Month, lopMonHocDTO.Buoi2.Value.Day, viewModel.SC2 == 0 ? 8 : 13, 0, 0);
                    }
                    if (viewModel.Buoi3 != null)
                    {
                        lopMonHocDTO.Buoi3 = new DateTime(lopMonHocDTO.Buoi3.Value.Year, lopMonHocDTO.Buoi3.Value.Month, lopMonHocDTO.Buoi3.Value.Day, viewModel.SC3 == 0 ? 8 : 13, 0, 0);
                    }
                    if (ModelState.IsValid)
                    {
                        _lopMonHocCommandService.UpdateLopMonHoc(lopMonHocDTO);
                    }
                }
                if (ModelState.IsValid)
                {
                    return RedirectToAction("DanhSachMoLopHocKySau");
                }
                else
                {
                    viewModel.DanhSachLopThucHanh = _lopMonHocReportService.GetAllLopMonHoc().Where(lop => lop.MaLopChinh == viewModel.LopMonHocId && lop.LoaiLop != 0
);
                }
            }
            if (viewModel.MaMonHoc != null && !viewModel.MaMonHoc.Equals(Guid.Empty))
                viewModel.MonHoc = _monHocReportService.GetMonHocById(viewModel.MaMonHoc);
            if (viewModel.MaGiangVien1 != null && !viewModel.MaGiangVien1.Equals(Guid.Empty))
                viewModel.GiangVien1 = _giangVienReportService.GetGiangVienById(viewModel.MaGiangVien1);
            if (viewModel.MaGiangVien2 != null && !viewModel.MaGiangVien1.Equals(Guid.Empty))
                viewModel.GiangVien2 = _giangVienReportService.GetGiangVienById((Guid)viewModel.MaGiangVien2);
            if (viewModel.MaLopChinh != null && !viewModel.MaLopChinh.Equals(Guid.Empty))
                viewModel.LopChinh = _lopMonHocReportService.GetLopMonHocById((Guid)viewModel.MaLopChinh);

            viewModel.DanhSachHocKy = _hocKyReportService.GetAllHocKy().OrderBy(hk => hk.TenHocKy).OrderBy(hk => hk.NamHoc.Nam1);
            viewModel.DanhSachCa = _tietHocService.GetAllCa();
            viewModel.DanhSachLopSinhVien = _lopMonHocReportService.GetAllLopSinhVien().OrderBy(lop => lop.KhoaNam);
            viewModel.DanhSachTiet = _tietHocService.GetAllTietHoc(null, null, null);
            return View(viewModel);
        }

        [HttpPost]
        public JsonResult XoaLopMonHoc(Guid? maLop)
        {
            try
            {
                if (maLop.HasValue)
                {
                    _lopMonHocCommandService.DeleteLopMonHocById(maLop.Value);
                    return Json(new { 
                        success = true
                    });
                }
                else
                    return Json(new
                    {
                        success = false,
                        message = "Không tìm thấy lớp này."
                    });
            }
            catch (Exception exception)
            {
                return Json(new { 
                    success = false,
                    message = exception.Message
                });
            }
        }

        [HttpGet]
        public ActionResult LayDanhSachMonHoc(Guid? maGiangVien, Guid maLop)
        {
            IEnumerable<MonHocViewModel> danhSachMonHoc;
            if (maGiangVien != null)
                danhSachMonHoc = MonHocViewModel.FromMonHocDTOList(_giangVienReportService.GetAllMonHocByGiangVienId((Guid)maGiangVien).OrderBy(lop => lop.HocKy));
            else
                danhSachMonHoc = MonHocViewModel.FromMonHocDTOList(_monHocReportService.GetAllMonHoc(maLop).OrderBy(lop => lop.HocKy));
            return View(danhSachMonHoc);
        }

        [HttpGet]
        public ActionResult LayDanhSachGiangVien(Guid? monHocId, Guid? giangVienId)
        {
            List<GiangVienViewModel> danhSachGiangVien = new List<GiangVienViewModel>();
            if (monHocId != null)
            {
                Guid id = (Guid)monHocId;
                danhSachGiangVien = GiangVienViewModel.FromGiangVienDTOList(_monHocReportService.GetAllGiangVienByMonHocId(id)).ToList();
            }
            else
                danhSachGiangVien = GiangVienViewModel.FromGiangVienDTOList(_giangVienReportService.GetAllGiangVien()).ToList();
            if (giangVienId != null)
            {
                Guid gvId = (Guid)giangVienId;
                int index = danhSachGiangVien.FindIndex(m => m.ID == gvId);
                if (index >= 0)
                    danhSachGiangVien.RemoveAt(index);
            }
            return View(danhSachGiangVien);
        }

        [HttpGet]
        public ActionResult LayDanhSachLopMonHoc(Guid? maLopMonHoc)
        {
            IEnumerable<LopMonHocViewModel> danhSachLopMonHoc = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHoc());
            return View(danhSachLopMonHoc);
        }

        [HttpGet]
        public ActionResult LayDanhSachLopLyThuyet(Guid? maLopMonHoc, Guid? maMonHoc, Guid? maHocKy)
        {
            IEnumerable<LopMonHocViewModel> lopMonHocList = new List<LopMonHocViewModel>();
            if (maMonHoc.HasValue && maHocKy.HasValue && maLopMonHoc.HasValue)
            {
                lopMonHocList = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKy.Value, maMonHoc.Value, null, null, null).Where(l => l.LoaiLop == 0 && l.LopMonHocId != maLopMonHoc.Value));
            }
            return View(lopMonHocList);
        }

        [HttpGet]
        public ActionResult ChonLichGiangDayDialog(Guid? maLopMonHoc, Guid? maMonHoc, Guid? maGiangVien1, Guid? maGiangVien2, Guid? maLopSinhVien, Guid? maHocKy)
        {
            ChonLichGiangDayDialogViewModel viewModel = new ChonLichGiangDayDialogViewModel();
            viewModel.DanhSachKhongDuocChon = new List<KhaNangObject>();
            try
            {
                if (maLopMonHoc.HasValue && maMonHoc.HasValue && maGiangVien1.HasValue && maLopSinhVien.HasValue && maHocKy.HasValue)
                {
                    var lopMonHoc = _lopMonHocReportService.GetLopMonHocById(maLopMonHoc.Value);
                    var monHoc = _monHocReportService.GetMonHocById(maMonHoc.Value);
                    viewModel.SoTinChiLyThuyet = monHoc.SoTinChiLyThuyet;
                    if (lopMonHoc.LoaiLop == 0) //Ly Thuyet
                    {
                        viewModel.LaLopThucHanh = false;
                        var danhSachLopTrung = _lopMonHocReportService.GetAllLopMonHocTheoGiangVienTrongHocKy(maGiangVien1.Value, maHocKy.Value, null, null, true).ToList();
                        danhSachLopTrung.AddRange(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKy.Value, null, null, true).Where(lop => lop.LopSinhVienId == maLopSinhVien.Value));
                        foreach (LopMonHocDTO lop in danhSachLopTrung)
                        {
                            viewModel.DanhSachKhongDuocChon.Add(new KhaNangObject
                            {
                                KhaNangString = lop.KhaNangDuocChonString,
                                SoTinChiLyThuyet = lop.MonHoc.SoTinChiLyThuyet
                            });
                        }
                        var danhSachKhaNang = _giangVienReportService.GetAllLichRanh(maGiangVien1.Value, null, null);
                    }
                    else
                    {
                        viewModel.LaLopThucHanh = true;
                    }
                }
            }
            catch (Exception exception)
            {
                log.Error(exception.Message, exception);
            }
            return View(viewModel);
        }

        [HttpGet]
        public JsonResult LayThongTinTietHoc(int tietDau, int tietSau)
        {
            try
            {
                var tietDauDTO = _tietHocService.GetAllTietHoc(tietDau, null, null).First();
                var tietSauDTO = _tietHocService.GetAllTietHoc(tietSau, null, null).First();
                return Json(new
                {
                    success = true,
                    TietDau = tietDauDTO,
                    TietSau = tietSauDTO
                }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception exception)
            {
                log.Error(exception.Message, exception);
                return Json(new { 
                    success = false
                }, JsonRequestBehavior.AllowGet);
            }
        }

        [HttpPost]
        public ActionResult XacNhanMoLop(Guid? maLopMonHoc, bool dongYMo = true)
        {
            string message = "Cập nhật không thành công.";
            if (maLopMonHoc != null)
            {
                try
                {
                    if (dongYMo)
                    {
                        var lopMonHoc = _lopMonHocReportService.GetLopMonHocById((Guid)maLopMonHoc);
                        lopMonHoc.DongYMoLop = true;
                        _lopMonHocCommandService.UpdateLopMonHoc(lopMonHoc);
                    }
                    else
                    {
                        _lopMonHocCommandService.DeleteLopMonHocById((Guid)maLopMonHoc);
                    }
                return Json(new { 
                    success = true
                });
                }
                catch (Exception exception)
                {
                    message = exception.Message;
                }
            }
            return Json(new { 
                success = false,
                message = message
            });
        }

        [HttpGet]
        public ActionResult DanhSachLopDeNghiMo()
        {
            Guid maHocKyHienTai;
            IEnumerable<LopMonHocViewModel> danhSachDeNghiMoViewModel = new List<LopMonHocViewModel>();
            if (Guid.TryParse(_thamSoService.GetThamSo("HocKyHienTai"), out maHocKyHienTai))
            {
                danhSachDeNghiMoViewModel = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, null, null, false));
            }
            return View(danhSachDeNghiMoViewModel);
        }

        [HttpGet]
        [HandleError]
        public ActionResult XemLichThi()
        {
            var viewModel = new DanhSachLichThiViewModel();
            try
            {
                var hocKyHienTai = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYHIENTAI);
                viewModel.DanhSachLopMonHoc = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(hocKyHienTai, true, true, true));
                viewModel.DanhSachLichThi = _lichThiReportService.GetAllLichThi(hocKyHienTai, null, null, null);
                viewModel.SortLichThiByLopMonHoc();
            }
            catch (Exception exception)
            {
                log.Error(exception.Message, exception);
            }
            return View(viewModel);
        }

        [HttpPost]
        public JsonResult XoaDangKyLichThi(Guid? maDangKyLichThi)
        {
            string duocphepdk = _thamSoService.GetThamSo("ChoPhepDangKyLichThi");
            bool success = true;
            string message = "Xoá thành công!";
            bool duocphep = (duocphepdk == null ? false : bool.Parse(duocphepdk));
            if (!duocphep)
            {
                success = false;
                message = "Tính năng chưa được kích hoạt để sử dụng! Vui lòng liên hệ admin!";
                return Json(new { success = success, message = message });
            }     

            try
            {
                if (maDangKyLichThi.HasValue)
                {
                    _lichThiCommandService.DeleteLichThi(maDangKyLichThi.Value);
                    return Json(new
                    {
                        success = true,
                        message=message
                    });
                }
                else
                {
                    return Json(new { 
                        success = false,
                        message = "Không tồn tại đăng ký này."

                    });
                }
            }
            catch (Exception exception)
            {
                return Json(new { 
                    success = false,
                    message = exception.Message
                });
 
            }

        }

        [HttpGet]
        public ActionResult SuaLichThiDialog(Guid? maLopMonHoc)
        {
            if (maLopMonHoc != null && maLopMonHoc != Guid.Empty)
            {
                DangKyLichThiViewModel viewModel;
                var lopMonHoc = _lopMonHocReportService.GetLopMonHocById((Guid)maLopMonHoc);

                var lichThi = _lichThiReportService.GetAllLichThi(null, null, null, maLopMonHoc);
                if (lichThi.Count() > 0)
                {
                    var lichThiLopMonHoc = lichThi.First();
                    viewModel = DangKyLichThiViewModel.FromLichThiDTO(lichThiLopMonHoc);
                }
                else
                {
                    viewModel = new DangKyLichThiViewModel();
                    viewModel.MaLopMonHoc = (Guid)maLopMonHoc;
                    viewModel.LopMonHoc = lopMonHoc;
                }
                return View(viewModel);
            }
            else
                return HttpNotFound();
        }

        [HttpGet]
        public ActionResult XuatFileLichThiDialog()
        {
            XuatFileLichThiViewModel viewModel = new XuatFileLichThiViewModel();
            viewModel.danhSachFileMau = _taiLieuReportService.GetAllTaiLieu(UserUtility.GetCurrentUser().MaNguoiDung, true, _thamSoService.GetGuid(ThamSoConstantUtility.MALOAIFILEMAU), null, null);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult XuatFileLichThi(Guid? FileMau)
        {
            Stream fileStream;
            string fileName, contentType;
            if (!FileMau.HasValue)
                return HttpNotFound();
            bool readSuccess = _fileService.GetFileStreamById((Guid)FileMau, out fileStream, out fileName, out contentType);
            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = new byte[4096];
            while (true)
            {
                int readDataCount = fileStream.Read(buffer, 0, buffer.Length);
                if (readDataCount <= 0)
                    break;
                memoryStream.Write(buffer, 0, readDataCount);
            }
            fileStream.Close();

            Guid maHocKyHienTai = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYHIENTAI);
            var viewModel = new DanhSachLichThiViewModel();
            viewModel.DanhSachLopMonHoc = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true));
            viewModel.DanhSachLichThi = _lichThiReportService.GetAllLichThi(maHocKyHienTai, null, null, null);
            viewModel.SortLichThiByLopMonHoc();
            //var dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => lop.MaTietDau != null && lop.MaTietSau != null);
            List<LichThiTemplateModel> templateModelList = new List<LichThiTemplateModel>();
            int stt = 1;

            foreach (var lopMonHoc in viewModel.DanhSachLopMonHoc)
            {
                foreach (var lichThi in lopMonHoc.DanhSachLichThi)
                {
                    LichThiTemplateModel model = new LichThiTemplateModel();
                    model.STT = stt++;
                    model.MaLop = lopMonHoc.MaLopDayDu.Replace(" ", "");
                    model.TenMonHoc = lopMonHoc.MonHoc.TenMonHoc;
                    model.TenGiangVien = lopMonHoc.GiangVien1.GetTenVaHocVi();
                    model.NgayThi = lichThi.NgayGio.ToShortDateString();
                    model.SoSinhVienToiDa = lopMonHoc.SiSoToiDa;
                    model.ThoiGianThi = GetThoiGianThi(lichThi.NgayGio, lichThi.ThoiGianLamBai);
                    model.HinhThucThi = lichThi.HinhThucThi == 0 ? "Lý thuyết" : lichThi.HinhThucThi == 1 ? "Báo cáo" : "Thực hành";
                    model.GhiChu = lichThi.GhiChu;
                    templateModelList.Add(model);
                }
                
            }

            var tokenList = _excelService.GetAllTokenFromTemplate(ThamSoConstantUtility.LICHTHITEMPLATE);

            uint startRowIndex;
            memoryStream.Seek(0, SeekOrigin.Begin);
            var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
            _excelService.ExportToExcelWithTemplate<LichThiTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return File(memoryStream, contentType, fileName);
        }

        [HttpPost]
        public ActionResult XuatFileLichThiDefault()
        {
            Stream fileStream;
            string fileName, contentType;
            var taiLieu = _taiLieuReportService.GetTaiLieuById(_thamSoService.GetGuid(ThamSoConstantUtility.MATAILIEUDANHSACHLICHTHI));
            Guid fileId;
            if (taiLieu == null)
                throw new Exception("Chưa chọn file mẫu.");
            fileId = taiLieu.MaTapTin;
            bool readSuccess = _fileService.GetFileStreamById(fileId, out fileStream, out fileName, out contentType);
            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = new byte[4096];
            while (true)
            {
                int readDataCount = fileStream.Read(buffer, 0, buffer.Length);
                if (readDataCount <= 0)
                    break;
                memoryStream.Write(buffer, 0, readDataCount);
            }
            fileStream.Close();

            Guid maHocKyHienTai = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYHIENTAI);
            var viewModel = new DanhSachLichThiViewModel();
            viewModel.DanhSachLopMonHoc = LopMonHocViewModel.FromLopMonHocDTOList(_lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true));
            viewModel.DanhSachLichThi = _lichThiReportService.GetAllLichThi(maHocKyHienTai, null, null, null);
            viewModel.SortLichThiByLopMonHoc();
            //var dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => lop.MaTietDau != null && lop.MaTietSau != null);
            List<LichThiTemplateModel> templateModelList = new List<LichThiTemplateModel>();
            int stt = 1;

            foreach (var lopMonHoc in viewModel.DanhSachLopMonHoc)
            {
                foreach (var lichThi in lopMonHoc.DanhSachLichThi)
                {
                    LichThiTemplateModel model = new LichThiTemplateModel();
                    model.STT = stt++;
                    model.MaLop = lopMonHoc.MaLopDayDu.Replace(" ", "");
                    model.TenMonHoc = lopMonHoc.MonHoc.TenMonHoc;
                    model.TenGiangVien = lopMonHoc.GiangVien1.GetTenVaHocVi();
                    model.NgayThi = lichThi.NgayGio.ToShortDateString();
                    model.SoSinhVienToiDa = lopMonHoc.SiSoToiDa;
                    model.ThoiGianThi = GetThoiGianThi(lichThi.NgayGio, lichThi.ThoiGianLamBai);
                    model.HinhThucThi = lichThi.HinhThucThi == 0 ? "Lý thuyết" : lichThi.HinhThucThi == 1 ? "Báo cáo" : "Thực hành";
                    model.GhiChu = lichThi.GhiChu;
                    templateModelList.Add(model);
                }

            }

            var tokenList = _excelService.GetAllTokenFromTemplate(ThamSoConstantUtility.LICHTHITEMPLATE);

            uint startRowIndex;
            memoryStream.Seek(0, SeekOrigin.Begin);
            var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
            _excelService.ExportToExcelWithTemplate<LichThiTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return File(memoryStream, contentType, fileName);
        }

        public ActionResult KhoaLuanTotNghiep()
        {
            var hocKyHienTai = _thamSoService.GetGuid(ThamSoConstantUtility.HOCKYHIENTAI);
            var danhSachKhoaLuan = DeTaiViewModel.FromDeTaiDTOList(_deTaiReportService.GetAllDeTai(null, null, hocKyHienTai, null, null, null));
            return View(danhSachKhoaLuan);
        }

        [HttpGet]
        public ActionResult ChiTietDetai(Guid maDeTai)
        {
            var deTaiViewModel = DeTaiViewModel.FromDeTaiDTO(_deTaiReportService.GetDeTaiById(maDeTai));
            return View(deTaiViewModel);
        }

        [HttpGet]
        public ActionResult HuyDeTai(Guid maDeTai)
        {
            DeTaiViewModel viewModel = new DeTaiViewModel();
            viewModel.MaDeTai = maDeTai;
            return View(viewModel);
        }


        [HttpPost]
        public JsonResult XacNhanDeTai(Guid maDeTai, bool datYeuCau, string lyDoHuy)
        {
            try
            {
                _deTaiCommandService.XacNhanDeTai(maDeTai, datYeuCau, lyDoHuy ?? string.Empty);
            }
            catch (Exception exception)
            {
                return Json(new { 
                    success=false,
                    message = exception.Message
                });
            }
            return Json(new { 
                success=true
            });
        }

        [HttpGet]
        public ActionResult XuatFileDialog()
        {
            XuatLichViewModel viewModel = new XuatLichViewModel();
            viewModel.danhSachFileMau = _taiLieuReportService.GetAllTaiLieu(UserUtility.GetCurrentUser().MaNguoiDung, true, _thamSoService.GetGuid(ThamSoConstantUtility.MALOAIFILEMAU), null, null);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult XuatFile(XuatLichViewModel viewModel)
        {
            Stream fileStream;
            string fileName, contentType;
            if (ModelState.IsValid)
            {
                if (viewModel.FileMau.Equals(Guid.Empty))
                {
                    ModelState.AddModelError("", "File mẫu không tồn tại.");
                    viewModel.danhSachFileMau = _taiLieuReportService.GetAllTaiLieu(UserUtility.GetCurrentUser().MaNguoiDung, true, _thamSoService.GetGuid(ThamSoConstantUtility.MALOAIFILEMAU), null, null);
                    return View(viewModel);
                }

                bool readSuccess = _fileService.GetFileStreamById(viewModel.FileMau, out fileStream, out fileName, out contentType);
                MemoryStream memoryStream = new MemoryStream();
                byte[] buffer = new byte[4096];
                while (true)
                {
                    int readDataCount = fileStream.Read(buffer, 0, buffer.Length);
                    if (readDataCount <= 0)
                        break;
                    memoryStream.Write(buffer, 0, readDataCount);
                }
                fileStream.Close();

                Guid maHocKyHienTai = Guid.Parse(_thamSoService.GetThamSo("HocKyHienTai"));
                var dsLopMonHoc = new List<LopMonHocDTO>();
                dsLopMonHoc = _lopMonHocReportService.GetAllLopMonHocTheoHocKy(maHocKyHienTai, true, true, true).Where(lop => viewModel.BaoGomChuaXepLich == true || (viewModel.BaoGomChuaXepLich == false && lop.MaTietDau != null && lop.MaTietSau != null)).ToList();
                switch (viewModel.Filter)
                {
                    case 1:
                        { // Chi lop ly thuyet
                            dsLopMonHoc = dsLopMonHoc.Where(lop => lop.LoaiLop == 0).ToList();
                            break;
                        }
                    case 2:
                        { // Chi lop thuc hanh
                            dsLopMonHoc = dsLopMonHoc.Where(lop => lop.LoaiLop != 0).ToList();
                            break;
                        }
                    default: break;
                }
                List<DangKyHocPhanTemplateModel> templateModelList = new List<DangKyHocPhanTemplateModel>();
                int stt = 1;
                foreach (var lopMonHocDTO in dsLopMonHoc)
                {
                    DangKyHocPhanTemplateModel model = _lopMonHocReportService.LayThongTinDangKyHocPhanCuaLop(lopMonHocDTO.LopMonHocId);
                    model.STT = stt++;
                    templateModelList.Add(model);
                }
                var tokenList = _excelService.GetAllTokenFromTemplate(ThamSoConstantUtility.DKHPTEMPLATE);

                uint startRowIndex;
                memoryStream.Seek(0, SeekOrigin.Begin);
                var templateInfo = _excelService.GetInfoFromTemplateFile(memoryStream, tokenList, out startRowIndex);
                _excelService.ExportToExcelWithTemplate<DangKyHocPhanTemplateModel>(ref memoryStream, templateInfo.ToList(), templateModelList, startRowIndex);
                memoryStream.Seek(0, SeekOrigin.Begin);
                return File(memoryStream, contentType, fileName);
            }
            else
            {
                viewModel.danhSachFileMau = _taiLieuReportService.GetAllTaiLieu(UserUtility.GetCurrentUser().MaNguoiDung, true, _thamSoService.GetGuid(ThamSoConstantUtility.MALOAIFILEMAU), null, null);
                return View(viewModel);
            }
        }

        #region
        private String GetThoiGianThi(DateTime ngayGio, int thoiGianLamBai)
        {
            var fromHour = ngayGio.Hour < 10 ? "0" + ngayGio.Hour.ToString() : ngayGio.Hour.ToString();
            var fromMinute = ngayGio.Minute < 10 ? "0" + ngayGio.Minute.ToString() : ngayGio.Minute.ToString();
            var toHour = ngayGio.AddMinutes(thoiGianLamBai).Hour < 10 ? "0" + ngayGio.AddMinutes(thoiGianLamBai).Hour.ToString() : ngayGio.AddMinutes(thoiGianLamBai).Hour.ToString();
            var toMinute = ngayGio.AddMinutes(thoiGianLamBai).Minute < 10 ? "0" + ngayGio.AddMinutes(thoiGianLamBai).Minute.ToString() : ngayGio.AddMinutes(thoiGianLamBai).Minute.ToString();

            return (fromHour + "h") + (fromMinute + " - " + (toHour + "h") + toMinute);
        }
        #endregion
    }
}
